package main

import "fmt"

func main() {
	//for循环中声明多个变量
	var sum int
	for i, j, k := 0, 1, 2; (i < 20) && (j < 10) && (k < 30); i, j, k = i+1, j+1, k+5 {
		sum += i + j + k
		fmt.Print(sum, " ") //3 13 30 54 85 123
	}
	println()

	/* for语句的变体 */
	//省略前置语句
	i := 0
	for ; i < 10; i++ {
		i++
	}
	//省略后置语句
	for i := 0; i < 10; {
		i++
	}
	//省略前置和后置语句
	for i < 10 {
		println(i)
		i++
	}
	//全都省略,类似于PHP的 while 循环
	m := 0
	for {
		println("死循环")
		m++
		if m >= 3 {
			break
		}
	}

	/* for ... range  */
	var map1 = map[string]int{
		"zhangsan": 18,
		"lisi":     22,
		"wangwu":   15,
	}
	for k, v := range map1 {
		fmt.Print(k, "=>", v, "; ") //lisi=>22; wangwu=>15; zhangsan=>18;
	}
	println()

	//如果不关心元素的值，可以省略元素值的变量，只声明下标
	for i := range map1 {
		fmt.Print(i, " ") //zhangsan lisi wangwu
	}
	println()

	//如果不关心元素下标，只关心元素值，可以用空标识符替代下标
	for _, v := range map1 {
		fmt.Print(v, " ") //18 22 15
	}
	println()

	//如果既不关心下标值也不关心元素值,只是循环它的次数
	for _, _ = range map1 {
		fmt.Print("A", " ") //A A A
	}
	println()

	//或者可以直接这样写
	for range map1 {
		fmt.Print("B", " ") //B B B
	}
	println()

	// 使用 for...range 遍历英文和中文字符串
	var str1 = "hello"
	for k, v := range str1 {
		fmt.Printf("%d => %c ,", k, v) //0 => h ,1 => e ,2 => l ,3 => l ,4 => o ,
	}
	println()

	var str2 = "你好呀"
	for k, v := range str2 {
		fmt.Printf("%d => %c ,", k, v)                    //0 => 你 ,3 => 好 ,6 => 呀 ,
		fmt.Printf("%d -> %s -> 0x%x, ", k, string(v), v) //0 -> 你 -> 0x4f60, 3 -> 好 -> 0x597d, 6 -> 呀 -> 0x5440,
	}
	println()

	//使用break/continue,并可以加标签跳转到指定位置
out:
	for i := 1; i <= 5; i++ {
		for j := 1; j <= 5; j++ {
			if j == 2 {
				break out //i:1,j:1
				//continue out
				/*
					i:1,j:1
					i:2,j:1
					i:3,j:1
					i:4,j:1
					i:5,j:1
				*/
			}
			fmt.Printf("i:%d,j:%d\n", i, j)
		}
	}
	println()

	//goto语句
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			fmt.Printf("i:%d,j:%d\n", i, j)
			if j == 2 {
				goto breakHere
			}
			fmt.Println("这里的内容不会跳过")
		}
		fmt.Println("这里的内容会跳过1")
	}
	fmt.Println("这里的内容会跳过2")
	fmt.Println("一直到breakHere标记之间的内容都会跳过")

breakHere:
	fmt.Println("直接跳到这里来了")

}
